using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Data.Sql;

namespace SqlTools.Utility
{
	public class Server
	{
		private const string CONN_INTAUTH_INSTANCED = "Data Source={0}\\{1};Integrated Security=True;Initial Catalog={2}";
		private const string CONN_INTAUTH_DEFAULT = "Data Source={0};Integrated Security=True;Initial Catalog={1}";
		private const string CONN_INSTANCED = "Data Source={0}\\{1};User ID={2};Password={3};Initial Catalog={4}";
		private const string CONN_DEFAULT = "Data Source={0};User ID={1};Password={2};Initial Catalog={3}";

		private string _serverName;
		private string _instance;

		private string _user;
		private string _password;

		private bool _integratedAuthentication;

		public string ServerName
		{
			get { return _serverName; }
			set { _serverName = value; }
		}

		public string Instance
		{
			get { return _instance; }
			set { _instance = value; }
		}

		public string FullName
		{
			get
			{
				string ret = _serverName;

				if ( !string.IsNullOrEmpty(_instance) )
				{
					ret += "\\" + _instance;
				}

				return ret;
			}
		}

		public bool UseIntegratedAuthentication
		{
			get { return _integratedAuthentication; }
			set { _integratedAuthentication = value; }
		}

		public string Username
		{
			get { return _user; }
			set { _user = value; }
		}

		public string Password
		{
			get { return _password; }
			set { _password = value; }
		}

		/// <summary>
		/// Connects to the SQL Server specified by serverName and instance.  
		/// Integrated authentication is used.
		/// </summary>
		/// <param name="serverName">The name of the server to connect to.</param>
		/// <param name="instance">The instance of SQL Server on the target machine.  
		/// Pass String.Empty for the default instance.</param>
		public Server(string serverName, string instance)
		{
			_serverName = serverName;
			_instance = instance;
			_integratedAuthentication = true;

			_user = "";
			_password = "";
		}

		/// <summary>
		/// Connects to the SQL Server specified by serverName and instance,
		/// and uses user and password for authentication.
		/// </summary>
		/// <param name="serverName">The name of the server to connect to.</param>
		/// <param name="instance">The instance of SQL Server on the target machine.
		/// Pass String.Empty for the default instance.</param>
		/// <param name="user">The user name to use for authentication.</param>
		/// <param name="password">The password for <paramref>user</paramref></param>
		public Server(string serverName, string instance, string user, string password)
		{
			_serverName = serverName;
			_instance = instance;
			_integratedAuthentication = false;

			_user = user;
			_password = password;
		}

		public List<string> GetDatabaseList()
		{
			List<string> dbs = new List<string>();

			using ( SqlConnection conn = new SqlConnection(GetDatabaseConnectionString("master")) )
			{

				try
				{
					conn.Open();

					SqlCommand cmd = new SqlCommand("SELECT * FROM sysdatabases", conn);
					cmd.CommandType = CommandType.Text;

					SqlDataReader sdr = cmd.ExecuteReader();

					while ( sdr.Read() )
					{
						dbs.Add(sdr["name"].ToString());
					}
				}
				//catch ( SqlException sex )
				//{

				//}
				finally
				{
					if ( conn.State == ConnectionState.Open )
					{
						conn.Close();
					}
				}
			}

			return dbs;
		}

		public static string GetDatabaseConnectionString(string serverName, string instanceName, string dbName)
		{
			if ( instanceName == String.Empty )
			{
				return String.Format(CONN_INTAUTH_DEFAULT, serverName, dbName);
			}
			else
			{
				return String.Format(CONN_INTAUTH_INSTANCED, serverName, instanceName, dbName);
			}
		}

		public static string GetDatabaseConnectionString(string serverName, string instanceName, string dbName, string username, string password)
		{
			if ( instanceName == String.Empty )
			{
				return String.Format(CONN_DEFAULT, serverName, username, password, dbName);
			}
			else
			{
				return String.Format(CONN_INSTANCED, serverName, instanceName, username, password, dbName);
			}
		}

		public string GetDatabaseConnectionString(string dbName)
		{
			if ( _integratedAuthentication )
			{
				return Server.GetDatabaseConnectionString(_serverName, _instance, dbName);
			}
			else
			{
				return Server.GetDatabaseConnectionString(_serverName, _instance, dbName, _user, _password);
			}
		}

		public static List<Server> GetServerList()
		{
			SqlDataSourceEnumerator dsEnum = SqlDataSourceEnumerator.Instance;

			DataTable dt = dsEnum.GetDataSources();

			List<Server> list = new List<Server>(dt.Rows.Count);

			foreach ( DataRow dr in dt.Rows )
			{
				Server server = new Server(dr["ServerName"].ToString(), dr["InstanceName"].ToString());
				list.Add(server);
			}

			return list;
		}

		public static Server FromFullName(string fullname)
		{
			string serverName = "";
			string instanceName = "";
			// check for instance name
			if ( fullname.IndexOf("\\") >= 0 )
			{
				string[] parts = fullname.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);

				if ( parts.Length >= 2 )
				{
					serverName = parts[0];
					instanceName = parts[1];
				}
			}
			else
			{
				serverName = fullname;
			}

			return new Server(serverName, instanceName);
		}
	}
}
